Skip to content

fix/Add public interface compatibility checks (closes #37) - #173

Merged
El-swaggerito merged 1 commit into
Aegis-RWA:mainfrom
rexx010:fix/37-interface-compatibility-checks
Jul 29, 2026
Merged

fix/Add public interface compatibility checks (closes #37)#173
El-swaggerito merged 1 commit into
Aegis-RWA:mainfrom
rexx010:fix/37-interface-compatibility-checks

Conversation

@rexx010

@rexx010 rexx010 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Closes #37

Summary

capabilities.rs already exposes a versioned capability-flag registry
(get_capabilities, supports_capability, get_capability_keys), but there
was no single call an SDK/dashboard client could make to answer "can I
safely integrate with this deployment?"
— clients had to hand-roll the
comparison themselves, or skip it and discover a gap only when a transaction
they assumed would succeed reverts.

This PR adds check_interface_compatibility: a pure-read entrypoint that
takes a client's schema version and its list of required capability keys,
and returns a precise, actionable report.

This is diagnostic tooling only — it does not gate authorization, and per
the issue's note, protocol-level compatibility is not legal or financial
advice. That caveat is stated explicitly in the new doc.

What changed

src/capabilities.rs (+107 lines, inserted after get_capability_keys, starting at line 577)

  • L577–598SchemaVersionRelation enum: Matching / ClientOlder / ClientNewer, derived from comparing client_schema_version to CAPABILITY_SCHEMA_VERSION.
  • L600–624InterfaceCompatibilityReport struct: contract_schema_version, client_schema_version, schema_relation, unsupported_required: Vec<Symbol>, compatible: bool.
  • L626–671check_interface_compatibility() free function. Re-derives every answer by calling the existing supports_capability() per requested key, so it can never disagree with get_capabilities / the key registry — no duplicated logic, no second source of truth.
  • L708–714AegisContract::check_interface_compatibility(env, client_schema_version, required_capabilities) public contract entrypoint, added to the existing impl AegisContract block alongside get_capabilities, supports_capability, get_capability_keys.

Characteristics (matching the existing capability-flag functions): no storage
writes, no events, no authorization required, never panics, callable before
initialize and while paused.

src/test.rs (+137 lines: import update + 7 new tests, L4282–L4412)

All under the new // ─── Public interface compatibility checks (#37) ─── section:

Test What it proves
test_interface_compatibility_matching_schema_and_supported_keys_is_compatible Same schema version + all-supported keys → Matching, compatible == true
test_interface_compatibility_older_client_schema_is_still_compatible Older client schema is forward-compatible if its requirements are met
test_interface_compatibility_newer_client_schema_flags_gap_when_relevant Newer client schema requiring an unknown key is correctly flagged as incompatible
test_interface_compatibility_reports_every_unsupported_required_key Multiple unsupported keys (Unsupported + Planned) are all aggregated, not just the first
test_interface_compatibility_empty_requirements_always_compatible No requirements ⇒ always compatible regardless of schema drift
test_interface_compatibility_agrees_with_supports_capability Cross-checks the report against the independent supports_capability call — the two can't silently diverge
test_interface_compatibility_never_mutates_and_works_before_initialize Callable pre-initialize, with no auth, and never mutates state

docs/interface-compatibility.md (new, 122 lines)

Full field reference, the schema_relation decision table, and SDK/dashboard
usage guidance (when to call it, how to build required_capabilities, how to
branch on compatible vs. schema_relation). Explicitly states this is not
a permission/compliance check and not legal or financial advice.

docs/capabilities.md (+8 lines)

Added a check_interface_compatibility entry to the API reference,
cross-linking the new doc.

docs/contract-spec.md (+1 line)

Added check_interface_compatibility to the Read Functions list (line 116),
matching the existing entries for get_capabilities / supports_capability
/ get_capability_keys.

README.md (+3 lines)

Linked the new docs/interface-compatibility.md, and also linked the
existing (previously unlinked) docs/capabilities.md from the docs index.

No changes to Cargo.toml / Cargo.lock — purely additive, no new
dependencies, no new error codes, no new storage keys.

Traceability mapping

Acceptance criterion Where it's satisfied
Public interface compatibility checks is implemented check_interface_compatibility in src/capabilities.rs (L577–714)
Relevant edge cases and failure states are handled Matching/older/newer schema, multiple unsupported keys, empty requirements, unknown-key fail-safe — src/test.rs L4282–4412
Security and compliance-sensitive assumptions are documented "Not a permission or compliance check" callout + not-legal-advice note in docs/interface-compatibility.md
Tests, fixtures, or review checklists added 7 new tests in src/test.rs, cross-checked against supports_capability
README or docs link to the new guidance README.md docs index, docs/capabilities.md, docs/contract-spec.md
Compatible with the rest of the Aegis ecosystem Reuses CAPABILITY_SCHEMA_VERSION and supports_capability as its only data source; no new storage/error surface

Verification

Ran locally against the full suite on the standard Rust/soroban-sdk 26 toolchain:

  • cargo test --lib: 187 passed, 0 failed (180 pre-existing + 7 new interface_compatibility tests). Baseline before this change: 180 passed, 0 failed.
  • cargo test interface_compatibility -- --nocapture: all 7 new tests pass individually.
  • No new warnings introduced. The only remaining unused import: AssetStatusChangedEvent warning pre-dates this change and is unrelated.
  • git diff main...HEAD --stat confirms exactly the six files listed above changed — no stray edits.

Suggested commands for reviewers

cargo test capabilities
cargo test interface_compatibility

Add check_interface_compatibility, a pure-read entrypoint that lets an
SDK/dashboard client verify its required capability keys and schema
version against a specific Aegis deployment before integrating, instead
of discovering a gap mid-transaction.

- src/capabilities.rs: SchemaVersionRelation enum, InterfaceCompatibilityReport
  struct, check_interface_compatibility() free fn, and the
  AegisContract::check_interface_compatibility contract entrypoint.
  Re-derives every answer from the existing supports_capability helper
  so it can never disagree with get_capabilities / the key registry.
  No storage writes, no events, no auth required, callable pre-init and
  while paused.
- src/test.rs: 7 tests covering matching/older/newer client schema,
  aggregation of multiple unsupported required keys, agreement with
  supports_capability, the empty-requirements case, and the
  no-mutation / pre-initialize guarantee.
- docs/interface-compatibility.md: new contributor doc covering the API,
  the schema_relation table, and SDK/dashboard usage guidance.
- docs/capabilities.md, docs/contract-spec.md, README.md: cross-link the
  new doc and entrypoint from the existing capability-flag references.

No new storage keys, error codes, or auth changes. Purely additive;
Cargo.lock/Cargo.toml untouched.
@El-swaggerito
El-swaggerito merged commit 462a36a into Aegis-RWA:main Jul 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add public interface compatibility checks

2 participants